import axios from 'axios'
import { Toast } from 'vant'
import store from '../store/index'
import bigInt from 'json-bigint' // 处理大数使用
import { exchangeTokenAPI } from '@/API/userAPI.js'
import router from '@/router/index.js'

// 创建处理大数的方法
const transBigInt = data => {
  if (!data) return ''
  return bigInt.parse(data)
}

// 创建axios实例 赋值给request常量
const instance = axios.create({
  baseURL: 'http://toutiao-app.itheima.net',
  // transformResponse 数组是用来指定“中间件函数”的，用来对服务器响应的数据进行预处理
  transformResponse: [transBigInt]
})

// 添加请求拦截器
instance.interceptors.request.use(function (config) {
  // 在请求拦截器展示loading效果
  Toast.loading({
    message: '加载中...',
    duration: 0 // 为0时 toast 不会消失
  })

  const tokenStr = store.state.tokenInfo.token // 接收从store传过来的token
  // console.log(tokenStr)
  if (tokenStr) {
    config.headers.Authorization = `Bearer ${tokenStr}` //  如果有token那么给请求头添加身份认证字段  注意Bearer后面要有一个空格
    // console.log(config)
  }

  // console.log('请求拦截器')
  return config
}, function (error) {
  // 对请求错误做些什么
  return Promise.reject(error)
})

// 添加响应拦截器
instance.interceptors.response.use(function (response) {
  // 在响应拦截器清除loading效果
  Toast.clear()

  return response
}, async function (error) {
  // 请求失败也在响应拦截器清除loading效果

  // 方法2
  // 判断是否为token过期导致的请求失败
  const tokenInfo = store.state.tokenInfo
  // 如果有错误响应体,并且错误响应状态码为401,而且有refresh_token
  if (error.response && error.response.status === 401 && tokenInfo.refresh_token) {
    console.log('我要用refresh_token替换token')
    // 先发请求获取到新的token
    try {
      const { data: res } = await exchangeTokenAPI(tokenInfo.refresh_token)
      if (res.message) {
        console.log('我是返回的新token:' + res.data.token)
        // 传入的参数以一个对象的形式表示
        store.commit('updateTokenInfo', { token: res.data.token, refresh_token: tokenInfo.refresh_token })

        // error.config 是上次发送失败的请求的基础配置项
        return instance(error.config) // 返回的是一个promise对象
      }
    } catch { // 如果token和refresh token都过期的话
      // 清空vuex数据和localStorage
      store.commit('clearState')
      // 同时跳转到登录页
      router.push('/login?pre=' + router.currentRoute.fullPath)
    }
  }
  Toast.clear()
  return Promise.reject(error)
})

// 导出实例request
export default instance
